package com.jt.www.common.controller;

import com.alibaba.fastjson.JSONObject;
import com.jt.www.model.reps.GenericDataResponse;
import com.jt.www.util.wx.HttpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @Author zy
 * @Description 微信分享
 * @Date 2020-02-11 11:19
 **/
@Api(value = "微信分享接口", tags = {"WYB-WECHAT-API"}, description = "微信分享接口")
@RestController
@RequestMapping(value = "weChat")
public class WeChatController {

    public static final Logger log = LoggerFactory.getLogger(WeChatController.class);
    @Value("${remote.wxb_gzh_appId}")
    private String appId;

    @Value("${remote.wxb_gzh_appSecret}")
    private String appSecret;

    @Value("${remote.weixin_access_token_url}")
    private String accessTokenUrl;

    @Value("${remote.weixin_access_ticket_url}")
    private String apiTicketUrl;
    //微信参数
    private String accessToken;
    private String jsApiTicket;
    //获取参数的时刻
    private Long getTiketTime = 0L;
    private Long getTokenTime = 0L;
    //参数的有效时间,单位是秒(s)
    private Long tokenExpireTime = 0L;
    private Long ticketExpireTime = 0L;

    //字节数组转换为十六进制字符串
    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    //生成随机字符串
    private static String createNonceStr() {
        return UUID.randomUUID().toString();
    }

    //生成时间戳
    private static String createTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

    @ApiOperation(value = "微信分享接口", notes = "微信分享接口", httpMethod = "POST")
    @PostMapping(value = "weChatShare", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    @ApiResponses({@ApiResponse(code = 200, response = String.class, message = "微信分享接口")})
    public ResponseEntity<?> getWechatParam(String shareUrl) {
        //当前时间
        if ("".equals(shareUrl) || shareUrl == null) {
            return GenericDataResponse.errorWithMsg("分享链接不可为空！");
        } else {
            //对编码链接进行解码
          /*  try{
                shareUrl = java.net.URLDecoder.decode(shareUrl,"UTF-8");
                log.info("shareUrl====>"+shareUrl);
            }catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }*/
        }
        long now = System.currentTimeMillis();
        log.info("currentTime====>" + now + "ms");

        //判断accessToken是否已经存在或者token是否过期
        if (StringUtils.isBlank(accessToken) || (now - getTokenTime > tokenExpireTime * 1000)) {
            JSONObject tokenInfo = getAccessToken();
            if (tokenInfo != null) {
                accessToken = tokenInfo.getString("access_token");
                tokenExpireTime = tokenInfo.getLongValue("expires_in");
                //获取token的时间
                getTokenTime = System.currentTimeMillis();
            } else {
                log.info("====>tokenInfo is null~");
                return GenericDataResponse.errorWithMsg("token获取失败！");
            }

        }

        //判断jsApiTicket是否已经存在或者是否过期
        if (StringUtils.isBlank(jsApiTicket) || (now - getTiketTime > ticketExpireTime * 1000)) {
            JSONObject ticketInfo = getJsApiTicket();
            if (ticketInfo != null) {
                jsApiTicket = ticketInfo.getString("ticket");
                ticketExpireTime = ticketInfo.getLongValue("expires_in");
                getTiketTime = System.currentTimeMillis();
            } else {
                log.info("====>ticketInfo is null~");
                return GenericDataResponse.errorWithMsg("ticket获取失败！");
            }
        }

        //生成微信权限验证的参数
        Map<String, String> wechatParam = makeWXTicket(jsApiTicket, shareUrl);
        return GenericDataResponse.okWithData(wechatParam);
    }

    //获取accessToken
    private JSONObject getAccessToken() {
        //String accessTokenUrl = https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
        String requestUrl = accessTokenUrl + "&appid=" + appId + "&secret=" + appSecret;
        JSONObject result = HttpUtil.doGet(requestUrl);
        return result;
    }

    //获取ticket
    private JSONObject getJsApiTicket() {
        //String apiTicketUrl = https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
        String requestUrl = apiTicketUrl + "?access_token=" + accessToken + "&type=jsapi";
        JSONObject result = HttpUtil.doGet(requestUrl);
        return result;
    }

    //生成微信权限验证的参数
    public Map<String, String> makeWXTicket(String jsApiTicket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonceStr = createNonceStr();
        String timestamp = createTimestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写，且必须有序
        string1 = "jsapi_ticket=" + jsApiTicket +
                "&noncestr=" + nonceStr +
                "&timestamp=" + timestamp +
                "&url=" + url;
        log.info("String1=====>" + string1);
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        } catch (NoSuchAlgorithmException e) {
            log.error("WeChatController.makeWXTicket=====Start");
            log.error(e.getMessage(), e);
            log.error("WeChatController.makeWXTicket=====End");
        } catch (UnsupportedEncodingException e) {
            log.error("WeChatController.makeWXTicket=====Start");
            log.error(e.getMessage(), e);
            log.error("WeChatController.makeWXTicket=====End");
        }

        ret.put("url", url);
        ret.put("jsapi_ticket", jsApiTicket);
        ret.put("nonceStr", nonceStr);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        ret.put("appid", appId);

        return ret;
    }
}
